#include "client.h"
#define EPOLL_ARR_SIZE 100
extern int clientfd_all[2];
void* thread_func(void* arg) {//考虑使用结构体封装传入的参数(client_task_t,port)
    thread_task_t t_task = *(thread_task_t*)arg;
    //先绑定新端口的连接
    int clientfd2 = tcpinit(t_task.ip,t_task.port);//阻塞等待主线程给子线程发送
    clientfd_all[1] = clientfd2;
    //创建epoll实例监听pipe[0]和clientfd2
    int epfd = epoll_create1(0);
    if(epfd == -1){
        error(1,errno,"epoll_create1");
    }
    //对clientfd2和pipefd[0]进行监听
    addEpollReadfd(epfd, clientfd2);
    addEpollReadfd(epfd, t_task.pipefd);

    struct epoll_event * pEventArr = (struct epoll_event*)
        calloc(EPOLL_ARR_SIZE, sizeof(struct epoll_event));

    while(1){
        int nready = epoll_wait(epfd, pEventArr, EPOLL_ARR_SIZE, -1);
        if(nready == -1 && errno == EINTR) {
            continue;
        } else if(nready == -1) {
            ERROR_CHECK(nready, -1, "epoll_wait");
        } else {
            //大于0,遍历判断是主线程的消息还是server端返回文件资源
            client_task_t task;
            for(int i = 0; i < nready; ++i) {
                int fd = pEventArr[i].data.fd;
                if(fd == t_task.pipefd){//如果是客户端发消息
                    //先接受主线程的消息
                    memset(&task,0,sizeof(task));
                    task.peerfd = clientfd2;
                    task.pipefd = t_task.pipefd;
                    read(fd,&task.train.len,4);
                    printf("子线程读到的长度是%d\n",task.train.len);
                    read(fd,&task.train.type,4);
                    printf("子线程读到的类型是%d\n",task.train.type);
                    read(fd,&task.train.buff,task.train.len);
                    printf("子线程读到的内容是%s\n",task.train.buff);
                    //转发给server端
                    sendn(clientfd2,&task.train,8+task.train.len);
                    //初始化任务
                    if(task.train.type == CMD_TYPE_PUTS){//接受并判断是puts还是gets
                        //puts的具体实现
                        putsCommand(&task);
                    }
                }else if (fd == clientfd2){//如果是服务端发送文件资源
                    getsCommand(&task);
                }
            }
        }
    }
    return 0;
}

int addEpollReadfd(int epfd, int fd)
{
    struct epoll_event evt;
    memset(&evt, 0, sizeof(evt));
    evt.data.fd = fd;
    evt.events = EPOLLIN;
    int ret = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &evt);
    ERROR_CHECK(ret, -1, "epoll_ctl");
    return 0;
}

int delEpollReadfd(int epfd, int fd)
{
    struct epoll_event evt;
    memset(&evt, 0, sizeof(evt));
    evt.data.fd = fd;
    evt.events = EPOLLIN;
    int ret = epoll_ctl(epfd, EPOLL_CTL_DEL, fd, &evt);
    ERROR_CHECK(ret, -1, "epoll_ctl");
    return 0;
}

